package com.example.socket.filter;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.channel.socket.DatagramPacket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * DEBUG过滤器
 * @author Ramon
 */
@Sharable
public class DebugFilter extends ChannelDuplexHandler implements FilterHandler {

    private final static Logger logger = LoggerFactory.getLogger(DebugFilter.class);

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (logger.isDebugEnabled()) {
            if (msg instanceof ByteBuf) {
                ByteBuf buf = (ByteBuf) msg;
                buf.markReaderIndex();
                byte[] bytes = new byte[buf.readableBytes()];
                buf.readBytes(bytes);
                buf.resetReaderIndex();
                logger.debug("RECV - {}\n{}", msg, byte2hex(bytes, " "));
            } else if (msg instanceof DatagramPacket) {
                DatagramPacket dp = (DatagramPacket) msg;
                ByteBuf buf = dp.content();
                buf.markReaderIndex();
                byte[] bytes = new byte[buf.readableBytes()];
                buf.readBytes(bytes);
                buf.resetReaderIndex();
                logger.debug("RECV - {}\n{}", msg, byte2hex(bytes, " "));

            } else {
                logger.debug("RECV - {}", msg);
            }
        }
        super.channelRead(ctx, msg);

    }

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        if (logger.isDebugEnabled()) {
            if (msg instanceof ByteBuf) {
                ByteBuf buf = (ByteBuf) msg;
                buf.markReaderIndex();
                byte[] bytes = new byte[buf.readableBytes()];
                buf.readBytes(bytes);
                buf.resetReaderIndex();
                logger.debug("SEND - {}\n{}", msg, byte2hex(bytes, " "));
            } else if (msg instanceof DatagramPacket) {
                DatagramPacket dp = (DatagramPacket) msg;
                ByteBuf buf = dp.content();
                buf.markReaderIndex();
                byte[] bytes = new byte[buf.readableBytes()];
                buf.readBytes(bytes);
                buf.resetReaderIndex();
                logger.debug("SEND - {}\n{}", msg, byte2hex(bytes, " "));
            } else {
                logger.debug("SEND - {}", msg);
            }
        }
        super.write(ctx, msg, promise);
    }

    /**
     * 二行制转字符串
     * @param b
     * @param elide 分隔符
     * @return
     */
    public String byte2hex(byte[] b, String elide) {
        StringBuilder sb = new StringBuilder();
        String stmp = "";
        elide = elide == null ? "" : elide;
        for (int n = 0; b != null && n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                sb.append(elide).append("0").append(stmp);
            } else {
                sb.append(elide).append(stmp);
            }
        }
        return sb.toString().toUpperCase();
    }

    @Override
    public int getOrder() {
        return 10;
    }

    @Override
    public String getName() {
        return "debugFilter";
    }
}
